package com.example.backgroundmanger.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.backgroundmanger.commons.Result;
import com.example.backgroundmanger.commons.UserReadListener;
import com.example.backgroundmanger.entity.User;
import com.example.backgroundmanger.service.IUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.beans.factory.annotation.Value;
import com.example.backgroundmanger.utils.FileUploadUtil;
import com.example.backgroundmanger.utils.UserContext;
import com.example.backgroundmanger.dto.ChangePasswordRequest;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 坤哥
 * @since 2024-07-01
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户模块")
public class UserController  {
    //注入业务层
    @Resource
    private IUserService userService;
    //注入导入监听器
    @Resource
    private UserReadListener readListener;
    // 注入上传目录配置
    @Value("${file.upload-dir}")
    private String uploadDir;

// 用户注册
    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public Result register(@RequestBody User user) {
        userService.userRegisterService(user);
        return Result.success();
    }
    //用户登录
    @PostMapping("/login")
    @Operation(summary = "用户登录")
    //@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)；GET方式无请求体
    //如果前端传递的是data数据的对象,后端使用对象来接受,那么一定要添加@RequestBody
    public Result<Map<String,Object>> login(@RequestBody User user){
        Map<String,Object> map = (Map<String, Object>) userService.userLoginService(user.getUsername(),user.getPassword());
        return Result.success(200,"登录成功",map);
    }

    @GetMapping("/info")
    @Operation(summary = "获取用户信息")
    public Result<?> getUserInfo() {
        // 从拦截器中获取当前用户信息
        User currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            return Result.error(401, "用户信息获取失败");
        }
        return Result.success(currentUser);
    }


    //注销
    @PostMapping("/logout")
    @Operation(summary = "注销")
    //?代表不返回数据或是使用Void
    public Result<?> logout(){
        return Result.success();
    }

   // @RequestParam(value ="username",required = false)该参数不一定必须有值
    @PostMapping("/selectPageData")
    @Operation(summary = "根据分页查询用户列表")
    public Result<Map<String,Object>> selectPageData(int page,
                                                     int size,
                                                     @RequestParam(value ="username",required = false ) String username,
                                                     @RequestParam(value = "phone",required = false) String phone){
        Map<String,Object> map=new HashMap<>();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        //StringUtils.hasLength(username) 当用户名为空字符串或null的时候为false,则不执行该SQL条件
        wrapper.like(StringUtils.hasLength(username),User::getUsername,username)
                .like(StringUtils.hasLength(phone),User::getPhone,phone);
        wrapper.orderByDesc(User::getId);//根据id降序排列
        Page<User> p = new Page<>(page,size);
        Page<User> userPage = userService.page(p, wrapper);
        map.put("users",userPage.getRecords());//分页后的数据
        map.put("total",userPage.getTotal());//获取条数总量
        return Result.success(map);
    }

    @PostMapping("/updateStatusById")
    @Operation(summary = "修改用户状态")
    public Result<String> updateStatusById(@RequestBody User user){
            userService.updateById(user);
            return Result.success("修改成功!");
    }

    @PostMapping("/updateAndsave")
    @Operation(summary = "新增/编辑")
    public Result<String> updateAndsave(@RequestBody User user){
        if(user.getId()==null){
            userService.save(user);
            return Result.success("新增成功");
        }else{
            userService.updateById(user);
            return Result.success("编辑成功!");
        }
    }

    @PostMapping("/updateAndSave")
    @Operation(summary = "新增/编辑")
    public Result<String> updateAndSave(@RequestBody User user){
        if(user.getId()==null){//新增
            userService.save(user);
            return Result.success("新增成功!");
        }else{//编辑
            userService.updateById(user);
            return Result.success("修改成功!");
        }
    }

    @DeleteMapping("/delDataById/{id}")
    @Operation(summary = "根据ID删除数据")
    //@PathVariable:占位符注解,该参数是来自请求地址的占位符
    public Result<String> delDataById(@PathVariable int id){
        userService.removeById(id);
        return Result.success("删除成功");
    }

    @PostMapping("/delDataByIds")
    @Operation(summary = "批量删除")
    public Result<String> delDataByIds(@RequestBody List<Integer>  ids){
            userService.removeBatchByIds(ids);
            return Result.success("批量删除成功!");
    }

    @Operation(summary = "导出")
    @GetMapping("/exportOut")
    public void exportOut(HttpServletResponse response){
        try {
            //1.查询被导出的数据
            List<User> list = userService.list();
            //2.设置响应类型和响应头
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            String fileName = URLEncoder.encode("用户信息", "UTF-8");
            //告诉浏览器是数据下载
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            //3.将查询出的数据导出
            EasyExcel.write(response.getOutputStream(), User.class).sheet("人员信息").doWrite(list);
        } catch (Exception e) {
            throw new RuntimeException("导出出现异常...");
        }
    }

    //MultipartFile本身自身限制为1m也就是1024kb,因此文件过大不能上传,
    // 需要在yml去配置更大的字节量
    @Operation(summary = "导入")
    @PostMapping("/importData")
    public Result<String> importData(MultipartFile file) throws IOException {
        //通过监听器读取xlsx表中第一个sheet数据并封装到User对象中
        EasyExcel.read(file.getInputStream(),User.class, readListener).sheet().doRead();
        List<User> users = readListener.getUsers();
        //遍历users集合将数据存储到数据库中
        for (User u:users){
            u.setId(null);
            userService.save(u);
        }
        return Result.success("导入成功!");
    }

    /**
     * 上传用户头像
     * @param file 头像文件
     * @return 上传结果
     */
    @PostMapping("/uploadAvatar")
    public Result<?> uploadAvatar(@RequestParam("file") MultipartFile file) {
        try {
            // 上传路径
            String uploadPath = uploadDir + "/avatar";
            System.out.println("上传路径: " + uploadPath);
            
            // 上传文件
            String fileName = FileUploadUtil.uploadFile(file, uploadPath);
            
            // 文件访问路径 - 修改为不带/api前缀的路径
            String avatarUrl = "/avatar/" + fileName;  // 移除/api前缀
            
            // 从拦截器中获取当前用户信息
            User currentUser = UserContext.getCurrentUser();
            if (currentUser == null) {
                return Result.error(401, "用户信息获取失败");
            }
            
            // 根据用户ID查询用户
            User user = userService.getById(currentUser.getId());
            if (user == null) {
                return Result.error(400,"用户不存在");
            }
            
            user.setAvatar(avatarUrl);
            userService.updateById(user);
            
            return Result.success(avatarUrl);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(400,"头像上传失败：" + e.getMessage());
        }
    }

    /**
     * 修改密码
     * @param changePasswordRequest 修改密码请求
     * @return 修改结果
     */
    @PostMapping("/changePassword")
    @Operation(summary = "修改密码")
    public Result<?> changePassword(@RequestBody ChangePasswordRequest changePasswordRequest) {
        try {
            // 从拦截器中获取当前用户信息
            User currentUser = UserContext.getCurrentUser();
            if (currentUser == null) {
                return Result.error(401, "用户信息获取失败");
            }
            
            // 根据用户名查询完整的用户信息（包括密码）
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getUsername, currentUser.getUsername());
            User userWithPassword = userService.getOne(wrapper);
            
            if (userWithPassword == null) {
                return Result.error(404, "用户不存在");
            }
            
            // 验证旧密码
            if (!userWithPassword.getPassword().equals(changePasswordRequest.getOldPassword())) {
                return Result.error(400, "当前密码错误");
            }

            // 验证新密码和确认密码是否一致
            if (!changePasswordRequest.getNewPassword().equals(changePasswordRequest.getConfirmPassword())) {
                return Result.error(400, "两次输入的新密码不一致");
            }

            // 验证新密码和旧密码是否相同
            if (changePasswordRequest.getOldPassword().equals(changePasswordRequest.getNewPassword())) {
                return Result.error(400, "新密码不能与当前密码相同");
            }

            // 更新密码
            userWithPassword.setPassword(changePasswordRequest.getNewPassword());
            boolean success = userService.updateById(userWithPassword);
            
            if (success) {
                return Result.success();
            } else {
                return Result.error(400, "密码修改失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(400, "密码修改失败：" + e.getMessage());
        }
    }
}
